<html>
<head><meta charset="utf-8"><title>Implementing Send for a type that uses Rc internally · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing.20Send.20for.20a.20type.20that.20uses.20Rc.20internally.html">Implementing Send for a type that uses Rc internally</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="229210078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing%20Send%20for%20a%20type%20that%20uses%20Rc%20internally/near/229210078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Konrad Borowski <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing.20Send.20for.20a.20type.20that.20uses.20Rc.20internally.html#229210078">(Mar 07 2021 at 19:04)</a>:</h4>
<p>Is it fine to implement <code>Send</code> for a type that uses <code>Rc</code> internally for storing value in multiple fields within a structure (within-structure-reference-counting essentially) or should I implement my own version of <code>Rc</code> that is identical to one in the standard library?</p>
<p>For instance, let's say we have a vector that allows pushing a value from itself to its end (this is a rather weird example, I'm aware, the real code is <a href="https://docs.rs/clru/0.4.0/clru/struct.CLruCache.html">https://docs.rs/clru/0.4.0/clru/struct.CLruCache.html</a>, but this is much longer, and for additional context <a href="https://github.com/marmeladema/clru-rs/issues/39">https://github.com/marmeladema/clru-rs/issues/39</a>). <code>Rc</code> never leaves the structure, so sending <code>RcVec&lt;T&gt;</code> should send every <code>Rc</code> avoiding thread-safety issues, am I correct?</p>
<p>I'm aware that some things could break such an abstraction, for instance <code>RcVec</code> is not allowed to <code>derive(Clone)</code> as that would cause sending <code>RcVec</code> to not send every <code>Rc</code>.</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">thread</span><span class="p">;</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">rc</span>::<span class="n">Rc</span><span class="p">;</span><span class="w"></span>

<span class="cp">#[derive(Default, Debug)]</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">RcVec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Rc</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span><span class="p">);</span><span class="w"></span>

<span class="k">unsafe</span><span class="w"> </span><span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span>: <span class="nb">Send</span><span class="o">&gt;</span><span class="w"> </span><span class="nb">Send</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">RcVec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{}</span><span class="w"></span>

<span class="k">impl</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="n">RcVec</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">push_value</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">x</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">push</span><span class="p">(</span><span class="n">Rc</span>::<span class="n">new</span><span class="p">(</span><span class="n">x</span><span class="p">));</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">push_index</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">index</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="bp">self</span><span class="p">.</span><span class="mf">0.</span><span class="n">push</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="mi">0</span><span class="p">[</span><span class="n">index</span><span class="p">].</span><span class="n">clone</span><span class="p">());</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>

<span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RcVec</span>::<span class="n">default</span><span class="p">();</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">push_value</span><span class="p">(</span><span class="mi">42</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">x</span><span class="p">.</span><span class="n">push_index</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">thread</span>::<span class="n">spawn</span><span class="p">(</span><span class="k">move</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="n">x</span><span class="p">.</span><span class="n">push_value</span><span class="p">(</span><span class="mi">84</span><span class="p">);</span><span class="w"></span>
<span class="w">        </span><span class="fm">println!</span><span class="p">(</span><span class="s">"{:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">x</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="p">}).</span><span class="n">join</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="229212727"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing%20Send%20for%20a%20type%20that%20uses%20Rc%20internally/near/229212727" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing.20Send.20for.20a.20type.20that.20uses.20Rc.20internally.html#229212727">(Mar 07 2021 at 19:45)</a>:</h4>
<p><code>Rc</code> is not <code>Send</code> because its reference counting is not thread-safe. If it did and you cloned an <code>Rc</code>, move the clone to another thread, and then start cloning from both threads, the integer holding the reference count will be subject to data races. If your data type does not implement <code>Clone</code> in a way that would adjust <code>Rc</code>'s reference counts, then yeah, you could manually implement <code>Send</code> for your data structure.</p>



<a name="229231776"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing%20Send%20for%20a%20type%20that%20uses%20Rc%20internally/near/229231776" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing.20Send.20for.20a.20type.20that.20uses.20Rc.20internally.html#229231776">(Mar 08 2021 at 00:44)</a>:</h4>
<p>They also can't drop from another thread</p>



<a name="229614692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing%20Send%20for%20a%20type%20that%20uses%20Rc%20internally/near/229614692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/Implementing.20Send.20for.20a.20type.20that.20uses.20Rc.20internally.html#229614692">(Mar 10 2021 at 07:35)</a>:</h4>
<p>Just noting because you didn't mention it, use <code>Arc</code> <span aria-label="big smile" class="emoji emoji-1f604" role="img" title="big smile">:big_smile:</span></p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>